module i_cache #(parameter  A_WIDTH = 32,parameter C_INDEX = 10)(
    input[A_WIDTH-1:0] p_a,
    output[31:0] p_din,
    input p_strobe,
    output p_ready,
    input clk,clrn,
    output [A_WIDTH-1:0] m_a,
    input [31:0] m_dout,
    output m_strobe,
    input m_ready
);
    //regs
    localparam T_WIDTH = A_WIDTH - C_INDEX -2; // 1 block = 1 word
    reg valid0 [0:(1<<C_INDEX)-1];
    reg valid1 [0:(1<<C_INDEX)-1];
    reg [T_WIDTH-1:0] tags0 [0:(1<<C_INDEX)-1];
    reg [T_WIDTH-1:0] tags1 [0:(1<<C_INDEX)-1];
    reg [31:0] data0 [0:(1<<C_INDEX)-1];
    reg [31:0] data1 [0:(1<<C_INDEX)-1];
    reg LRUway [0:(1<<C_INDEX)-1];

    //control signals
    wire [C_INDEX-1:0] index = p_a[C_INDEX+1:2];
    wire [T_WIDTH-1:0] tag = p_a[A_WIDTH-1:C_INDEX+2];
    wire way0_hit = valid0[index] & (tags0[index] == tag);
    wire way1_hit = valid1[index] & (tags1[index] == tag);
    wire cache_hit = way0_hit | way1_hit;
    wire cache_miss = ~cache_hit;
    wire c_write = cache_miss & m_ready ;

    //datapath
    wire [31:0] c_dout = way0_hit ? data0[index] : data1[index];
    assign p_din = cache_hit ? c_dout : m_dout;
    assign p_ready = cache_hit | cache_miss & m_ready;
    assign m_a = p_a;
    assign m_strobe = p_strobe & cache_miss ; //read on miss
    wire [31:0] c_din = m_dout;
    
    //state transitions
    always @ (posedge clk)
        if(~clrn) begin
            valid0 <= '{default: '0};
            valid1 <= '{default: '0};
        end else if (c_write) begin
            if(LRUway[index] == 0) begin
                valid0[index] <= 1'b1;
                tags0[index] <= tag;
                data0[index] <= c_din;
                LRUway[index] <= 1'b1;
            end else begin
                valid1[index] <= 1'b1;
                tags1[index] <= tag;
                data1[index] <= c_din;
                LRUway[index] <= 1'b0;
            end
        end else begin
            if(way0_hit) begin
                LRUway[index] <= 1'b1;
            end else if(way1_hit) begin
                LRUway[index] <= 1'b0;
            end else begin
                LRUway[index] <= LRUway[index];
            end
        end
endmodule